//
//  UserReviewSettings.swift
//  hello
//
//  Created by 赵康 on 2025/3/30.
//


// UserReviewSettings.swift

import Vapor
import Fluent

final class UserReviewSettings: Model, Content, @unchecked Sendable {
    static var schema: String { SchemaEnum.userReviewSettings.rawValue }
    
    @ID(key: .id)
    var id: UUID?
    
    @Parent(key: FieldKeys.user)
    var user: User
    
    // 基本设置
    @Field(key: FieldKeys.dailyReviewCount)
    var dailyReviewCount: Int
    
    @Field(key: FieldKeys.prioritizeRecent)
    var prioritizeRecent: Bool
    
    @Field(key: FieldKeys.lastSyncDate)
    var lastSyncDate: Date?
    
    // 新增Anki算法设置
    // 新卡片设置
    @Field(key: FieldKeys.newCardsPerDay)
    var newCardsPerDay: Int
    
    @Field(key: FieldKeys.learningSteps)
    var learningSteps: [Int] // 以分钟为单位的学习步骤
    
    // 复习设置
    @Field(key: FieldKeys.maxReviewsPerDay)
    var maxReviewsPerDay: Int
    
    @Field(key: FieldKeys.intervalModifier)
    var intervalModifier: Double
    
    @Field(key: FieldKeys.maxInterval)
    var maxInterval: Int // 最大间隔(天)
    
    // 遗忘设置
    @Field(key: FieldKeys.lapseSteps)
    var lapseSteps: [Int] // 遗忘后的学习步骤(分钟)
    
    @Field(key: FieldKeys.lapseNewInterval)
    var lapseNewInterval: Double // 遗忘后间隔减少的百分比(0.0-1.0)
    
    @Field(key: FieldKeys.leechThreshold)
    var leechThreshold: Int // 连续多少次标记"忘记"后暂停
    
    @Timestamp(key: FieldKeys.createdAt, on: .create)
    var createdAt: Date?
    
    @Timestamp(key: FieldKeys.updatedAt, on: .update)
    var updatedAt: Date?
    
    init() { }
    
    init(
        id: UUID? = nil, 
        userID: User.IDValue, 
        dailyReviewCount: Int = 20,
        /** 设置用户每天复习卡片的目标数量，这是一个软性限制，限制范围是1-100 */
        
        prioritizeRecent: Bool = true,
        /** 是否优先复习最近的卡片，设置为true时，按照笔记ID降序排列，设为
        false时，按照到期时间排序后再随机打乱 */
        lastSyncDate: Date? = nil,
        // Anki默认设置
        newCardsPerDay: Int = 20,
        /** 限制服务器每天为用户生成的新卡片的数量，这是一个硬性限制，
         确保总量中新卡数量不会过多
         限制范围是1-1000*/
        learningSteps: [Int] = [1, 10], // 1分钟, 10分钟
        /**如果卡片仍在学习阶段(Learning)中：
         系统会将卡片推进到 learningSteps 数组中的下一个间隔
         假设 learningSteps = [1, 10, 60]：
         如果当前是第一步(1分钟)，选择"Good"后会进入第二步(10分钟)
         如果当前是第二步(10分钟)，选择"Good"后会进入第三步(60分钟)
         如果当前是最后一步(60分钟)，选择"Good"后会毕业进入复习阶段(Reviewing) */
        maxReviewsPerDay: Int = 100,
        /**maxReviewsPerDay 是总体硬性限制，
         决定了用户每天最多能看到多少张卡片（包括新卡片和复习卡片）**/
        intervalModifier: Double = 1.0,
        maxInterval: Int = 36500, // 100年
        lapseSteps: [Int] = [10], // 10分钟
        /**重续时的时间间隔**/
        lapseNewInterval: Double = 0.5, // 减少50%
        /**控制卡片回到正常的复习阶段后的第一个复习间隔
         假设有以下设置：
         
         lapseSteps = [10.0, 30.0, 60.0]（分钟）
         lapseNewInterval = 0.5
         原卡片间隔为20天
         当用户复习一张卡片并选择"Again"（完全忘记）时：
         
         阶段1：短期重新学习（由lapseSteps控制）
         卡片立即进入重新学习阶段(Relearning)
         系统安排在10分钟后再次显示此卡片
         如果用户选择"Good"，则30分钟后再次复习
         如果再次选择"Good"，则60分钟后再次复习
         如果最后一步也选择"Good"，卡片完成重新学习阶段
         阶段2：回到正常复习（由lapseNewInterval控制）
         系统计算新的复习间隔：20天 × 0.5 = 10天
         卡片状态改回"Reviewing"
         下一次常规复习将在10天后进行
**/
        leechThreshold: Int = 8
    ) {
        self.id = id
        self.$user.id = userID
        self.dailyReviewCount = dailyReviewCount
        self.prioritizeRecent = prioritizeRecent
        self.lastSyncDate = lastSyncDate
        
        // 初始化Anki设置
        self.newCardsPerDay = newCardsPerDay
        self.learningSteps = learningSteps
        self.maxReviewsPerDay = maxReviewsPerDay
        self.intervalModifier = intervalModifier
        self.maxInterval = maxInterval
        self.lapseSteps = lapseSteps
        self.lapseNewInterval = lapseNewInterval
        self.leechThreshold = leechThreshold
    }
    
    // 添加静态方法返回默认设置
    static func defaultSettings(userID: UUID) -> UserReviewSettings {
        return UserReviewSettings(
            userID: userID,
            dailyReviewCount: 20,
            prioritizeRecent: true,
            newCardsPerDay: 20,
            learningSteps: [1, 10],
            maxReviewsPerDay: 100,
            intervalModifier: 1.0,
            maxInterval: 36500,
            lapseSteps: [10],
            lapseNewInterval: 0.5,
            leechThreshold: 8
        )
    }
    
    // 设置更新请求
    struct Update: Content {
        // 基本设置
        let dailyReviewCount: Int?
        let prioritizeRecent: Bool?
        
        // Anki算法设置
        let newCardsPerDay: Int?
        let learningSteps: [Int]?
        let maxReviewsPerDay: Int?
        let intervalModifier: Double?
        let maxInterval: Int?
        let lapseSteps: [Int]?
        let lapseNewInterval: Double?
        let leechThreshold: Int?
    }
    
    // 设置响应
    struct Response: Content {
        let id: UUID?
        let userID: UUID
        
        // 基本设置
        let dailyReviewCount: Int
        let prioritizeRecent: Bool
        let lastSyncDate: Date?
        
        // Anki算法设置
        let newCardsPerDay: Int
        let learningSteps: [Int]
        let maxReviewsPerDay: Int
        let intervalModifier: Double
        let maxInterval: Int
        let lapseSteps: [Int]
        let lapseNewInterval: Double
        let leechThreshold: Int
        
        let createdAt: Date?
        let updatedAt: Date?
    }
}

  // 同步请求模型
struct SyncReviewData: Content {
  enum SyncDirection: String, Codable {
    case localToServer  // 本地覆盖服务器
    case serverToLocal  // 服务器覆盖本地
    case merge          // 合并 (可选功能)
  }
  
  let direction: SyncDirection
  let reviewData: [NoteReviewSync]
  
  struct NoteReviewSync: Content {
    let noteID: UUID
    let difficulty: NoteReview.Difficulty
    let nextReviewDate: Date?
    let reviewCount: Int
    let lastReviewDate: Date?
    // 添加Anki算法相关字段
    let easeFactor: Double?
    let interval: Double?
    let learningStage: NoteReview.LearningStage?
    let lapseCount: Int?
  }
}
